package com.lagou.edu.filter;

import com.lagou.edu.FeginClient.UserFeignClient;
import com.lagou.edu.strategy.DefaultRejectStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;


@Component
@Slf4j
public class GateWayFilter implements GlobalFilter, Ordered {



    @Value("${lagou.times}")
    private int times;
    @Value("${lagou.second}")
    private int second;

    Map<String,DefaultRejectStrategy> stopExploitMap = new ConcurrentHashMap<>();
    private static List<String> blackList = new ArrayList<>();



    @Autowired
    private UserFeignClient userFeignClient;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //开始时间
        long startTime = System.currentTimeMillis();

        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        String clientIp = request.getRemoteAddress().getHostString();
        String requestPath = request.getPath().toString();

        // 黑名单校验
        for (String s : blackList) {
            if (s.equals(clientIp)) {
                return reject(clientIp, response);
            }
        }


        // 添加黑名单
        if(requestPath.contains("/user/register/")) {
            DefaultRejectStrategy requestStrategy;
            if (!stopExploitMap.containsKey(clientIp)){
                requestStrategy = new DefaultRejectStrategy();
                stopExploitMap.put(clientIp,requestStrategy);
            }else {
                requestStrategy = stopExploitMap.get(clientIp);
                requestStrategy.add(second);
            }

            if(requestStrategy.checkIsAttack(times)) {
                System.out.println("在" + second + "秒请求次数达到: " + requestStrategy.getCount());
                blackList.add(clientIp);
                return reject(clientIp, response);
            }
        }


        // 合法请求放行
        return chain.filter(exchange);
    }

    private Mono<Void> reject(String ip, ServerHttpResponse response) {
        String data = "IP:" + ip  + "处于黑名单,无法访问.";
        System.out.println(data);
        DataBuffer wrap = response.bufferFactory().wrap(data.getBytes());
        return response.writeWith(Mono.just(wrap));
    }

    @Override
    public int getOrder() {
        return -1;
    }
}



